using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Terra.Data.Entities.Identity;

namespace Terra.Data.Configurations.Identity;

/// <summary>
/// Identity 模块实体配置
/// </summary>
public class IdentityEntityConfiguration :
    IEntityTypeConfiguration<User>,
    IEntityTypeConfiguration<Role>,
    IEntityTypeConfiguration<UserRole>,
    IEntityTypeConfiguration<UserClaim>,
    IEntityTypeConfiguration<RolePermission>,
    IEntityTypeConfiguration<Menu>,
    IEntityTypeConfiguration<Permission>
{
    /// <summary>
    /// 配置用户实体
    /// </summary>
    public void Configure(EntityTypeBuilder<User> builder)
    {

        builder.HasKey(x => x.Id);

        builder.HasIndex(x => x.UserName)
            .IsUnique()
            .HasDatabaseName("IX_Users_UserName");

        builder.HasIndex(x => x.Email)
            .IsUnique()
            .HasDatabaseName("IX_Users_Email");

        builder.Property(x => x.UserName)
            .IsRequired()
            .HasMaxLength(50);

        builder.Property(x => x.NormalizedUserName)
            .IsRequired()
            .HasMaxLength(50);

        builder.Property(x => x.Email)
            .IsRequired()
            .HasMaxLength(100);

        builder.Property(x => x.NormalizedEmail)
            .IsRequired()
            .HasMaxLength(100);
    }

    /// <summary>
    /// 配置角色实体
    /// </summary>
    public void Configure(EntityTypeBuilder<Role> builder)
    {

        builder.HasKey(x => x.Id);

        builder.HasIndex(x => x.Name)
            .IsUnique()
            .HasDatabaseName("IX_Roles_Name");

        builder.Property(x => x.Name)
            .IsRequired()
            .HasMaxLength(50);

        builder.Property(x => x.NormalizedName)
            .IsRequired()
            .HasMaxLength(50);

        builder.Property(x => x.Description)
            .HasMaxLength(200);
    }

    /// <summary>
    /// 配置用户角色关联
    /// </summary>
    public void Configure(EntityTypeBuilder<UserRole> builder)
    {

        builder.HasKey(x => x.Id);

        builder.HasIndex(x => new { x.UserId, x.RoleId })
            .IsUnique()
            .HasDatabaseName("IX_UserRoles_UserRole");

        builder.HasOne(x => x.User)
            .WithMany(x => x.UserRoles)
            .HasForeignKey(x => x.UserId)
            .OnDelete(DeleteBehavior.Cascade);

        builder.HasOne(x => x.Role)
            .WithMany()
            .HasForeignKey(x => x.RoleId)
            .OnDelete(DeleteBehavior.Cascade);
    }

    /// <summary>
    /// 配置用户声明
    /// </summary>
    public void Configure(EntityTypeBuilder<UserClaim> builder)
    {
        builder.ToTable("UserClaims");

        builder.HasKey(x => x.Id);

        builder.HasOne(x => x.User)
            .WithMany(x => x.UserClaims)
            .HasForeignKey(x => x.UserId)
            .OnDelete(DeleteBehavior.Cascade);

        builder.Property(x => x.ClaimType)
            .IsRequired()
            .HasMaxLength(100);

        builder.Property(x => x.ClaimValue)
            .HasMaxLength(1000);
    }

    /// <summary>
    /// 配置角色权限关联
    /// </summary>
    public void Configure(EntityTypeBuilder<RolePermission> builder)
    {

        builder.HasKey(e => e.Id);

        builder.HasIndex(e => new { e.RoleId, e.PermissionId })
              .IsUnique()
              .HasDatabaseName("IX_RolePermission_RolePermission");

        builder.HasOne(e => e.Role)
              .WithMany()
              .HasForeignKey(e => e.RoleId)
              .OnDelete(DeleteBehavior.Cascade);

        builder.HasOne(e => e.Permission)
              .WithMany()
              .HasForeignKey(e => e.PermissionId)
              .OnDelete(DeleteBehavior.Cascade);
    }

    /// <summary>
    /// 配置菜单实体
    /// </summary>
    /// <param name="builder"></param>
    public void Configure(EntityTypeBuilder<Menu> builder)
    {
        // 配置 Menu 和 Permission 的一对一关系
        builder
            .HasOne(m => m.Permission)
            .WithOne(p => p.Menu)
            .HasForeignKey<Permission>(p => p.MenuId)
            .OnDelete(DeleteBehavior.Cascade);

        // 配置索引
        builder.HasIndex(nameof(Menu.Name))
            .IsUnique()
            .HasDatabaseName("IX_Menu_Name");

        builder.HasIndex(nameof(Menu.AuthCode))
            .HasDatabaseName("IX_Menu_AuthCode");

        builder.HasIndex(nameof(Menu.ParentId))
            .HasDatabaseName("IX_Menu_ParentId");
    }

    /// <summary>
    /// 配置权限实体
    /// </summary>
    /// <param name="builder"></param>
    public void Configure(EntityTypeBuilder<Permission> builder)
    {
        // 配置 MenuId 唯一索引
        builder.HasIndex(p => p.MenuId)
            .IsUnique()
            .HasDatabaseName("IX_Permission_MenuId");

        // 配置其他索引
        builder.HasIndex(nameof(Permission.Code))
            .HasDatabaseName("IX_Permission_Code");

        builder.HasIndex(nameof(Permission.Type))
            .HasDatabaseName("IX_Permission_Type");
    }

}